package com.zyf.EasyNet.app.control;

import com.zyf.EasyNet.util.NeuralNetwork.ArrayUtils;
import com.zyf.EasyNet.util.NeuralNetwork.BpNetUtils;
import com.zyf.EasyNet.util.NeuralNetwork.DefaultData;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * @first_author zyflzz
 * @gmt_created 2022/6/5
 * @gmt_modified 2022/6/5
 */
@Controller
@Slf4j
public class SimulationControl {

    // private final static Logger log = LoggerFactory.getLogger(SimulationControl.class);

    @Autowired
    private ArrayUtils arrayUtils;

    @PostConstruct
    public void init() {
        log.info("SimulationControl START");
    }

    @GetMapping(path = "/data")
    public String getTempData(){
        return "data";
    }

    @GetMapping(path = "/simulation")
    public String getSimulation() {
        return "simulation";
    }

    @PostMapping(path = "/simulation")
    public String postSimulationConfig(String action,
                                       @RequestParam String learningRate,
                                       @RequestParam String exceptPrecision,
                                       @RequestParam String maxIterations,
                                       Map<String, Object> returnData) {
        switch (action) {
            case "play":
                BpNetUtils bpNetUtils = new BpNetUtils(DefaultData.getSample(), 4, DefaultData.getExcept());
                String result = bpNetUtils.bpIteration();
                log.info(parseCode(result));
                returnData.put("sample",arrayUtils.printMatrix(bpNetUtils.getSample()));
                returnData.put("except",arrayUtils.printMatrix(bpNetUtils.getExcept()));
                returnData.put("Epoch", bpNetUtils.getIterN());
                returnData.put("WeightIH",arrayUtils.printMatrix(bpNetUtils.getThetaIH()));
                returnData.put("WeightHO",arrayUtils.printMatrix(bpNetUtils.getThetaHO()));
                break;
            case "restart":
                return "simulation";
        }
        return "simulation";
    }

    /**
     * 解析迭代函数输出代码
     *
     * @param code 输出代码
     * @return 解析值
     */
    private String parseCode(String code) {
        StringBuilder stringBuilder = new StringBuilder("");
        int n = code.length();
        for (int i = 0; i < n; i++) {
            switch (code.charAt(i)) {
                case '0':
                    stringBuilder.append("执行成功，满足误差精度");
                    break;
                case '1':
                    stringBuilder.append("执行成功，完成所有迭代");
                    break;
                case '2':
                    stringBuilder.append("样本数组为空, ");
                    break;
                case '3':
                    stringBuilder.append("输入层-隐含层权重为空, ");
                    break;
                case '4':
                    stringBuilder.append("隐含层-输出层权重为空, ");
                    break;
                case '5':
                    stringBuilder.append("隐含层阈值为空, ");
                    break;
                case '6':
                    stringBuilder.append("输出层阈值为空, ");
                default:
                    break;
            }
        }
        return String.valueOf(stringBuilder);
    }
}
